using System;
using System.IO;

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Bcpg;

namespace Pbdms.Common.CryptoUtils
{
    /**
    * A simple utility class that Generates a RSA PgpPublicKey/PgpSecretKey pair.
    * <p>
    * usage: RsaKeyRingGenerator [-a] identity passPhrase</p>
    * <p>
    * Where identity is the name to be associated with the public key. The keys are placed
    * in the files pub.[asc|bpg] and secret.[asc|bpg].</p>
    */
    public sealed class RsaKeyRingGenerator
    {
        private string identity;
        private char[]  passPhrase;
        private AsymmetricCipherKeyPair kp;
        private IAsymmetricCipherKeyPairGenerator kpg;
        private Stream secretOut, publicOut;
        private PgpSecretKey secretKey;
        private PgpPublicKey publicKey;
        private RsaKeyRingGenerator()
        {
        }
        public RsaKeyRingGenerator(string id, char[] pass)
        {
            identity = id;
            this.passPhrase = pass;
            kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");

            kpg.Init(new RsaKeyGenerationParameters(
                BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25));

             kp = kpg.GenerateKeyPair();
        }
        public Boolean GenerateKeyPair()
        {
           
            try
            {//passPhrase,

                
                secretKey = new PgpSecretKey(
                PgpSignature.DefaultCertification,
                PublicKeyAlgorithmTag.RsaGeneral,
                kp.Public,
                kp.Private,
                DateTime.UtcNow,
                identity,
                SymmetricKeyAlgorithmTag.Cast5,
                passPhrase,
                null,
                null,
                new SecureRandom()
                );
                publicKey = secretKey.PublicKey;
                return true;
            }
            catch(Exception e)
            {
                Common.Global.showMsgOneButton("Unable to create a key/pair", 'I');
            }
            return false;
        }
        public PgpPublicKey getPublicKey()
        {
            return publicKey;
        }
        public PgpSecretKey getSecretKey()
        {
            return secretKey;
        }
        public Boolean exportToFile(string privatekeylocation, string publickeylocation)
        {
            Stream secretOut1=null, publicOut1=null; 
            try
            {
                //secretOut=new FileStream(privatekeylocation, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
                //publicOut = new FileStream(publickeylocation, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
                secretOut = File.Create(privatekeylocation);
                publicOut = File.Create(publickeylocation);
                secretOut1 = new ArmoredOutputStream(secretOut);
                secretKey.Encode(secretOut1);
                
                publicOut1 = new ArmoredOutputStream(publicOut);
                publicKey.Encode(publicOut1);
                
                secretOut1.Close();
                publicOut1.Close();
                publicOut.Close();
                secretOut.Close();
                return true;
            }
            catch (Exception e)
            {
                
                Common.Global.showMsgOneButton("Unable to create a key/pair", 'I');
            }
            finally
            {
                secretOut1.Close();
                publicOut1.Close();
                secretOut.Close();
                publicOut.Close();
                secretOut.Dispose();
                publicOut.Dispose();
            }
            return false;
        }
    }
}
